'''
=========================
limber.documents.document
=========================

This module contains an abstract class that defines
the document interface.
'''


class AbstractDocument(object):
    '''Defines the document interface.'''
    
    def __init__(self, path=None, mode=None):
        
        self._data = None
        self._title = None
        self._path = path
        self._modification_flag = False
        self._is_closed = False
        self._mode = mode
        self._encoding = None
        
        if self._path is not None:
            self.open(self._path, self._mode)
    
    @property
    def closed(self):
        '''Is `True` if the file is closed.'''
        
        return bool(self._is_closed)
    
    @property
    def name(self):
        '''The document's filename.'''
        
        return self._path
    
    @property
    def mode(self):
        '''The document's mode.'''
        
        return self._mode
    
    @property
    def encoding(self):
        '''The document's encoding.'''
        
        return self._encoding
    
    def __iter__(self):
        return self
    
    def next(self):
        '''Yield the next line of the file.'''
        
        return self.readline()
    
    def __enter__(self):
        '''Context handler that return self.'''
        
        return self
    
    def __exit__(self, exc_type, exc_value, exc_tb):
        '''Context handler that closes the file.'''
        
        self.close()
        return False
    
    def open(self, path, mode='r'):
        '''Open the document at the given path.'''
        
        raise NotImplementedError()
    
    def close(self):
        '''Close the document.'''
        
        raise NotImplementedError()
    
    def flush(self):
        '''Flush the document's content.'''
        
        raise NotImplementedError()
    
    def save(self):
        '''Save the current document.'''
        
        raise NotImplementedError()
    
    def reload(self):
        '''Reload the document in-place.'''
        
        raise NotImplementedError()
    
    def read(self, bytes=-1):
        '''Read *bytes* bytes from the document.
        
        This method is a low-level method that return
        the raw bytes of the document.
        '''
        
        raise NotImplementedError()
    
    def write(self, data):
        '''Write *data* to the document.
        
        This method is a low-level method that
        writes the raw bytes to the file.
        '''
        
        raise NotImplementedError()
    
    def tell(self):
        '''Return the index of the current byte.'''
        
        raise NotImplementedError()
    
    def seek(self, pos, mode=0):
        '''Changes the byte index.'''
        
        raise NotImplementedError()
    
    def readline(self, linesep='\n'):
        '''Read a line from the file.
        
        This method is a low-level method
        that return raw bytes from the file.
        
        The optional *linesep* parameter can be
        given to read non-textual lines.
        '''
        
        raise NotImplementedError()
    
    def readlines(self, linesep='\n'):
        '''Return an iterator over the lines.
        
        This method is a low-level method
        that return raw bytes from the file.
        
        The optional *linesep* parameter can be
        given to read non-textual lines.
        '''
        
        raise NotImplementedError()
    
    def writelines(self, lines, end=''):
        '''Write each line in *lines* to the file.'''
        
        raise NotImplementedError()
    
    def isatty(self):
        '''Return `True` if the document is a tty.'''
        
        return False
    
    def truncate(self, size=None):
        '''Truncates the file after *size* bytes.'''
        
        raise NotImplementedError()
    
    # Custom interface of limber documents.
    def title(self):
        '''Return the document's title.'''
        
        return self._title
    
    def set_title(self, title):
        '''Set the document's title.'''
        
        self._title = title
    
    def path(self):
        '''Return the document's path.'''
        
        return self._path
    
    def set_path(self, path):
        '''Set the document's path.'''
        
        self._path = path
    
    def is_modified(self):
        '''Return `True` if the document is modified.'''
        
        return bool(self._modification_flag)
    
    def set_modified(self, flag):
        '''Set the modification flag.'''
        
        self._modification_flag = flag
    
    def data(self, query=None, format=None):
        '''Return the document's data.
        
        This method is a high-level method.
        It return the data in a format suitable
        for views.
        
        The *query* argument can specifies which data
        to take, while the *format* argument
        specifies which format should have
        the returned data.
        '''
        
        raise NotImplementedError()
    
    def set_data(self, data, query=None, format=None):
        '''Set the document's data.
        
        This method is a high-level method.
        
        The *data* parameter contains the data to be written,
        the *query* parameter can specify how data should
        be inserted or overwritten, while the *format* parameter
        specifies which is the format of the incoming *data*.
        '''
        
        raise NotImplementedError()
    
